﻿using System.Collections.Generic;
using CoreEx.Database.Persistence;
using LinFu.IoC.Configuration;
using LinFu.IoC.Interfaces;
using LinFu.IoC;

namespace CoreEx.Database.Persistence.Implementation
{
    [Implements(typeof(IStateTrackerRepository),LifecycleType.Singleton)]
    public class StateTrackerRepository : IStateTrackerRepository, IInitialize
    {
        private readonly IDictionary<object, IStateTracker> _stateTrackers 
            = new Dictionary<object, IStateTracker>();

        private readonly IDictionary<object,IStateTracker> _targetStateTrackerReferences 
            = new Dictionary<object, IStateTracker>();

        private IServiceContainer _serviceContainer;

        

        public IStateTracker GetStateTracker<T>(T owner) where T:class
        {
            if (!_stateTrackers.ContainsKey(owner))
            {
                var stateTracker = _serviceContainer.GetService<IStateTracker>();
                stateTracker.ObjectRegistered += (stateTracker_ObjectRegistered);
                _stateTrackers.Add(owner, stateTracker);
            }
            
            return _stateTrackers[owner];
        }

        void stateTracker_ObjectRegistered(object sender, ObjectRegisteredEventArgs e)
        {
            if (!_targetStateTrackerReferences.ContainsKey(e.Target))
                _targetStateTrackerReferences.Add(e.Target,(IStateTracker)sender);
        }

        public void Release<T>(T owner) where T : class
        {
            if (_stateTrackers.ContainsKey(owner))
                _stateTrackers.Remove(owner);
        }

        public int Count
        {
            get
            {
                return _stateTrackers.Count;
            }
        }

        public bool IsTracked<T>(T target) where T : class
        {
            return _targetStateTrackerReferences.ContainsKey(target);
        }


        public IStateTracker GetStateTrackerByTarget<TTarget>(TTarget target) where TTarget : class
        {
            if (!_targetStateTrackerReferences.ContainsKey(target))
                return null;

            return _targetStateTrackerReferences[target];
        }


        public void Initialize(IServiceContainer source)
        {
            _serviceContainer = source;
        }
    }
}